﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SFP;
using SFP.Animation2D;
using SFP.Input;

namespace ParticleSystemCreator
{
    public class ParticleScene : Game
    {
        internal Form particleForm;
        ControlForm controlForm;

        internal ParticleSystem pSystem;

        long particleCount = 0;
        double particleCountTime = 0;
        double particleCountIntervall = 66;

        double clockTime = 0;
        int clockSec;
        int clockMin;
        int clockHrs;

        public ParticleScene(Size resolution, ControlForm controlForm) : base(resolution)
        {
            forbidClosing = true;
            showFPS = true;
            limitFrameRate = false;
            pauseGameOnInactiveForm = false;

            particleForm = GetForm();
            particleForm.Text = "Particle System";
            particleForm.Icon = global::ParticleSystemCreator.Properties.Resources.icon;
            particleForm.MaximizeBox = false;
            particleForm.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            particleForm.StartPosition = FormStartPosition.CenterScreen;

            this.controlForm = controlForm;
        }

        protected override void Initialize()
        {
            initializeParticleSystem();
            controlForm.applyPreferencesToParticleSystem();
        }

        private void initializeParticleSystem()
        {
            pSystem = new ParticleSystem();

            ParticleSystem.Emitter emitter = pSystem.GetEmitter();
            emitter.x = resolution.Width / 2;
            emitter.y = resolution.Height / 2;
        }

        protected override void LoadContent()
        {
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(double time)
        {
            KeyboardState keyStates = Keyboard.GetKeyboardState();

            updateParticleSystem(time, keyStates);
            updateClockTime(time);
        }

        private Nullable<Point> lastMouseLocation;

        public void updateParticleSystem(double time, KeyboardState keyStates)
        {
            ParticleSystem.Emitter emitter = pSystem.GetEmitter();

            /* Process mouse input... */

            if (Mouse.isLButtonClicked())
            {
                Point mLoc = Mouse.getCurrentLocation();

                if (keyStates.isKeyDown(Keys.ShiftKey))
                {
                    if (lastMouseLocation != null)
                    {
                        pSystem.X += mLoc.X - ((Point)lastMouseLocation).X;
                        pSystem.Y += mLoc.Y - ((Point)lastMouseLocation).Y;
                    }
                }
                else
                {
                    emitter.x = mLoc.X - pSystem.X;
                    emitter.y = mLoc.Y - pSystem.Y;
                }

                lastMouseLocation = mLoc;
            }
            else
            {
                lastMouseLocation = null;
            }

            /* Process keyboard input... */

            bool turboMove = false;
            if (keyStates.isKeyDown(Keys.ShiftKey))
            {
                turboMove = true;
            }

            double scrollValue = .1;
            if (turboMove) scrollValue *= 4;

            if (keyStates.isKeyDown(Keys.Left))
            {
                emitter.x -= scrollValue * time;
            }
            else if (keyStates.isKeyDown(Keys.Right))
            {
                emitter.x += scrollValue * time;
            }
            if (keyStates.isKeyDown(Keys.Up))
            {
                emitter.y -= scrollValue * time;
            }
            else if (keyStates.isKeyDown(Keys.Down))
            {
                emitter.y += scrollValue * time;
            }

            particleCountTime += time;

            if (particleCountTime > particleCountIntervall)
            {
                particleCount = pSystem.GetParticleCount();
                particleCountTime -= particleCountIntervall * (long)(particleCountTime / particleCountIntervall);
            }

            pSystem.update(time);
        }

        private void updateClockTime(double time)
        {
            clockTime += time;
            clockSec = (int)((clockTime / 1000) % 60);
            clockMin = (int)(((clockTime / 1000) / 60) % 60);
            clockHrs = (int)((((clockTime / 1000) / 60) / 60) % 24);
        }

        protected override void Draw(Graphics graphics)
        {
            /* Draw particles...*/
            pSystem.draw(graphics);
            graphics.FillRectangle(new SolidBrush(Color.Black), 5, 30, 140, 18);
            graphics.DrawString("Particles: " + particleCount, new Font("Arial", 12), new SolidBrush(Color.Yellow), new PointF(5, 30));

            /* Draw clock time... */
            DateTime currentTime = new DateTime(1, 1, 1, clockHrs, clockMin, clockSec);
            graphics.FillRectangle(new SolidBrush(Color.Black), resolution.Width - 95, 5, 92, 22);
            graphics.DrawString(currentTime.ToLongTimeString(), new Font("Arial", 16), new SolidBrush(Color.Yellow), new PointF(resolution.Width - 95, 5));
        }
    }
}
